#pragma once
#include <unordered_map>
#include <string>
#include <fstream>
#include "Log.hpp"
#include "InetAddr.hpp"

using namespace myLog;


//默认字典存放的路径
const std::string default_dict_path = "./dictionary.txt";
const std::string dict_sep = ": ";

class Dict{
private:
    //从对应文件中把字典加载到哈希表中
    void LoadDict(){
        //打开文件
        std::ifstream in(_dict_path);
        if(!in.is_open()){
            LOG(LogLevel::FATAL) << "The Dictionary opens fail!";
            exit(-1);
        }

        //正常打开后，把文件内的东西放到哈希表内
        std::string line; //apple: 苹果 

        while(std::getline(in, line)){
            //如果正常进来，说明一行被成功的读取到line内！
            int sep_pos = line.find(dict_sep);
            if(sep_pos == std::string::npos){
                LOG(LogLevel::WARNING) << "当前行解析失败 : " << line;
                continue;
            }

            std::string english = line.substr(0, sep_pos);
            std::string chinese = line.substr(sep_pos + dict_sep.size());

            if(english == "" || chinese == ""){
                LOG(LogLevel::WARNING) << "当前行获取出现空串 : " << line;
                continue;
            }

            //加入到字典哈希表中
            auto it = _dict_macth.emplace(english, chinese);
            if(it.second == false) LOG(LogLevel::WARNING) << "当前行加载失败 : " << line;
        }

        //关闭文件
        in.close();
    }

public:
    Dict(const std::string& dict_path = default_dict_path)
        :_dict_path(dict_path)
    {
        //得到路径后，就需要把对应的内容加载到哈希表上！
        LoadDict();
        LOG(LogLevel::DEBUG) << "字典加载成功" ;
    }
    ~Dict(){}
    
    //用于翻译
    std::string Translate(const std::string& word, const InetAddr& client){
        LOG(LogLevel::DEBUG) << "[" << client.GetIp() << " : " << client.GetPort() << "]# 申请翻译 " << word;
        auto it = _dict_macth.find(word);
        if(it == _dict_macth.end()) return "None";
        else {
            LOG(LogLevel::DEBUG) << "[" << client.GetIp() << " : " << client.GetPort() << "]# 进入翻译模块 翻译 " << word;
            return it->second;
        }
    }

    void Print(){
        for(auto& match : _dict_macth){
            std::cout << match.first << " : " << match.second << std::endl;
        }
    }

private:
    std::string _dict_path;
    std::unordered_map<std::string, std::string> _dict_macth;
};